﻿package com.fecesaids.greatgame.inventory {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.events.Event;
	import flash.geom.*;
	import flash.utils.Timer;
	import com.fecesaids.greatgame.utils.HitTester;
	public class Inventory extends Sprite{
		private var _inventoryArray:Array;

		private var _mouseDown:Boolean = false;
		private var _dragging:Boolean = false;
		private var _originX:int = 0;
		private var _originY:int = 0;
		private var _itemOffsetX:int;
		private var _itemOffsetY:int;
		private var _interiorBoundsRect = new Rectangle(13, 60, 142, 95);
		private var _boundsRect;
		private var _curSelectedItem:InventoryItem;
		private var _curSelectedItemIndex:int = -1;
		private var _itemMenu:ItemMenu;
		private var _clickTimer:Timer;
		private var _clickedItem:Object;
		
		private const _MINDRAG:int= 4;
		private const _CLICKDELAY:int= 250;
		private const _BRIGHTCOLOR = new ColorTransform(2, 2, 2);
		private const _DEFAULTCOLOR = new ColorTransform(1, 1, 1);
		
		public function Inventory():void {
			// Constructor
			this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			_inventoryArray = new Array();
			_clickTimer = new Timer(_CLICKDELAY, 1);
			_itemMenu = null;
			_boundsRect = new Rectangle(0, 0, this.width, this.height);
		}

		private function onMouseDown(event:MouseEvent):void {
			if(_itemMenu != null){
				if((mouseX < _itemMenu.x) || (mouseX > _itemMenu.x + _itemMenu.getWidth()) ||
				   (mouseY < _itemMenu.y) || (mouseY > _itemMenu.y + _itemMenu.getHeight())){
					_mouseDown = true;
					_originX = mouseX;
					_originY = mouseY;
					_itemOffsetX = event.localX;
					_itemOffsetY = event.localY;
				}
			}
			else{
				_mouseDown = true;
				_originX = mouseX;
				_originY = mouseY;
				_itemOffsetX = event.localX;
				_itemOffsetY = event.localY;
			}
		}
		private function deselectItemEvent(evt:Event):void{
			_curSelectedItem.transform.colorTransform = _DEFAULTCOLOR;
			_curSelectedItem.removeEventListener("deselectItem", deselectItem);
			_curSelectedItem = null; // We no longer are hovering over an item
			_curSelectedItemIndex = -1;
		}
		private function deselectItem():void{
			_curSelectedItem.transform.colorTransform = _DEFAULTCOLOR;
			_curSelectedItem.removeEventListener("deselectItem", deselectItem);
			_curSelectedItem = null; // We no longer are hovering over an item
			_curSelectedItemIndex = -1;
		}
		private function onMouseUp(event:MouseEvent):void {
			_mouseDown = false;
			if(_itemMenu != null){
				removeContextMenu();
			}
			if (_dragging) {
				_dragging = false;
				if(_curSelectedItem != null){
					var moved = false;
					if(_curSelectedItem.x < _interiorBoundsRect.x){
						_curSelectedItem.x = _interiorBoundsRect.x;
						moved = true;
					}
					else if(_curSelectedItem.x + _curSelectedItem.width > _interiorBoundsRect.x + _interiorBoundsRect.width){
						_curSelectedItem.x = _interiorBoundsRect.x + _interiorBoundsRect.width - _curSelectedItem.width;
						moved = true;
					}
					if(_curSelectedItem.y < _interiorBoundsRect.y){
						_curSelectedItem.y = _interiorBoundsRect.y;
						moved = true;
					}
					else if(_curSelectedItem.y + _curSelectedItem.height > _interiorBoundsRect.y + _interiorBoundsRect.height){
						_curSelectedItem.y = _interiorBoundsRect.y + _interiorBoundsRect.height - _curSelectedItem.height;
						moved = true;
					}
					if(moved){
						deselectItem();
					}
				}
				this.stopDrag()
			} else {
				if ((_clickTimer != null) && (_clickTimer.running)) {
					// Double click
					_clickTimer.stop();
					_clickTimer.reset();
					_clickTimer.removeEventListener("timer", timerHandler);
					if(event.target != this)
						_curSelectedItem.doUse();
				} else {
					// Clicked once so far
					_clickTimer.addEventListener("timer", timerHandler);
					_clickTimer.start();
					_clickedItem = event.target.parent;
				}
			}
		}

		private function onMouseMove(event:MouseEvent):void {
			if (_mouseDown) {
				if (!_dragging) {
					var p1 = new Point(mouseX, mouseY);
					var p2 = new Point(_originX, _originY);
					var distance = Point.distance(p1, p2);
					if (distance > _MINDRAG) {
						_dragging = true;
						if (_curSelectedItem == null) {
							this.startDrag();
						} else {
							_curSelectedItem.startDrag();
							_curSelectedItem.x = mouseX - _itemOffsetX;
							_curSelectedItem.y = mouseY - _itemOffsetY;
						}
						_clickTimer.stop();
						_clickTimer.reset();
						_clickTimer.removeEventListener("timer", timerHandler);
					}
					removeContextMenu();
				}
			} else {
				var arrayLength:int = _inventoryArray.length;
				var i:int;
				var foundItem:Boolean = false;
				for (i=arrayLength-1; ((i>=0)&&(foundItem == false)); i--) {
					if (HitTester.realHitTest(_inventoryArray[i], new Point(event.stageX, event.stageY))) {// If the mouse is over an item
						foundItem = true;
						if (_curSelectedItem != _inventoryArray[i]) {// If the item we found is not the currently selected item
							if (_curSelectedItem != null) {// If the current item is not null
								_curSelectedItem.transform.colorTransform = _DEFAULTCOLOR;// Set the current item to opaque
							}
							_curSelectedItem = _inventoryArray[i];
							_curSelectedItemIndex = i;
							_curSelectedItem.transform.colorTransform = _BRIGHTCOLOR;
							_curSelectedItem.addEventListener("deselectItem", deselectItemEvent);
						}
					}
				}
				if (!foundItem) {// If nothing is found than we no longer have the mouse over an item
					if (_curSelectedItem != null) {// If we were hovering over an item last time we checked
						deselectItem();
					}
				}
			}
		}

		private function timerHandler(event:TimerEvent):void {
			// Timer elapsed, single click confirmed
			_clickTimer.stop();
			_clickTimer.reset();
			_clickTimer.removeEventListener("timer", timerHandler);
			if ((_curSelectedItem != null) && (_itemMenu == null) && (_clickedItem == _curSelectedItem)) {
				drawContextMenu(_curSelectedItem.getOptions());
			}
		}
		// haven't fucked with really past here
		public function tryRemoveContextMenu(){
			if(_itemMenu != null){
				if(((mouseX < _itemMenu.x) || (mouseX > _itemMenu.x + _itemMenu.getWidth()))||
				  ((mouseY < _itemMenu.y) || (mouseY > _itemMenu.y + _itemMenu.getHeight())))
				{
					removeContextMenu();
				}
			}
		}
		private function removeContextMenu(){
			if(_itemMenu != null){
				removeChild(_itemMenu);
				_itemMenu.removeEventListener("menuItemClicked", menuItemClicked);
				_itemMenu = null;
			}
		}
		public function addInvItem(newInvItemData:Array){
			var dingle = new InventoryItem(newInvItemData);
			_inventoryArray.push(dingle);
		}
		public function remInvItem(itemData:Array){
			var numItems = _inventoryArray.length;
			var remCount = 0;
			var toRemCount = itemData[1];
			var f:int;
			var itemNumbersToRemove:Array = [];
			for(var i=0; i<numItems; i++){
				if((_inventoryArray[i].getBaseName() == itemData[0]) && (remCount < toRemCount)){
					remCount++;
					removeChild(_inventoryArray[i]);
					itemNumbersToRemove.push(i);
				}
			}
			
			//var numItems = _inventoryArray.length;
			var newArray = new Array();
			var g:int;
			for(f = 0; f < numItems; f++){
				var foundItem = false;
				for(g=0; g<itemNumbersToRemove.length;g++){
					if(f == itemNumbersToRemove[g]){
						foundItem = true;
					}
				}
				if(foundItem == false){
					newArray.push(_inventoryArray[f]);
				}
			}
			_inventoryArray = newArray;
		}
		public function checkFor(itemData:Array):Boolean {
			var itemName:String = itemData[0];
			var numNeed:int = itemData[1];
			var numCount:int = 0;
			var numOfInventoryItems:int = _inventoryArray.length;
			for(var i=0; i<numOfInventoryItems; i++){
				if(_inventoryArray[i].getBaseName() == itemName){
					numCount++;
				}
			}
			if(numCount >= numNeed){
				return true;
			}
			else{
				return false;
			}
		}
		public function getInvItem(invItemNumber:int):InventoryItem{
			return _inventoryArray[invItemNumber];
		}
		public function drawItems():void{
			var arrayLength:int = _inventoryArray.length;
			var i:int;
			for(i = 0; i < arrayLength; i++){
				addChild(_inventoryArray[i]);
			}
			randItemPlacement()
		}
		public function randItemPlacement(){
			var arrayLength:int = _inventoryArray.length;
			var i:int;
			for(i = 0; i < arrayLength; i++){
				var posX:int = (Math.random() * (142 - _inventoryArray[i].getWidth())) + 14;
				var posY:int = (Math.random() * (90 - _inventoryArray[i].getHeight())) + 64;
				_inventoryArray[i].setPos(posX, posY)
			}
		}
		private function drawContextMenu(optionArray:Array){
			if(_curSelectedItem != null){
				_itemMenu = new ItemMenu(optionArray, _curSelectedItem);
				_itemMenu.addEventListener("menuItemClicked", menuItemClicked);
				addChild(_itemMenu);
				if(mouseX + _itemMenu.getWidth() + this.x> stage.stageWidth){
					_itemMenu.x = stage.stageWidth - this.x - _itemMenu.getWidth() - 2;
				}
				else{
					_itemMenu.x = mouseX - 2;
				}
				if(mouseY + _itemMenu.getHeight() + this.y> stage.stageHeight){
					_itemMenu.y = stage.stageHeight - this.y - _itemMenu.getHeight() - 2;
				}
				else{
					_itemMenu.y = mouseY - 2;
				}
			}
		}
		private function menuItemClicked(evt:Event):void{
			var doFunction = _itemMenu.getDoFunction();
			_itemMenu.getMyObjectRef().doAction(doFunction);
		}
		private function repositionItem(item:InventoryItem):void{
			var posX:int = (Math.random() * (142 - item.getWidth())) + 14;
			var posY:int = (Math.random() * (90 - item.getHeight())) + 64;
			item.setPos(posX, posY)
		}
	}
}